package agent

import (
	"fmt"
	"github.com/beego/beego/v2/core/logs"
	"github.com/go-redis/redis"
	"strings"
	"time"
)

var (
	gRedisClient *redis.Client
	localAddr    string
)

func RedisInit(addr, passwd, localIp string) {

	gRedisClient = redis.NewClient(&redis.Options{
		Addr:         addr,
		Password:     passwd,
		PoolSize:     10,
		MinIdleConns: 2,
		IdleTimeout:  180 * time.Second,
		DB:           1,
	})

	res := gRedisClient.Ping()
	if res.Err() != nil {
		logs.Error("redis connect failed:%v", res.String())
		gRedisClient = nil
	} else {
		logs.Info("redis 连接成功,启用坐席状态同步......")
	}

	localAddr = localIp
}

func lockSet(company string) bool {

	lockName := fmt.Sprintf("%s_lock", company)
	res := gRedisClient.SetNX(lockName, localAddr, time.Second*30)

	logs.Debug("get lock:%v ", res.String())
	if res.Val() || strings.Contains(res.String(), localAddr) {
		return true
	}

	return false
}

func lockDel(company string) {

	lockName := fmt.Sprintf("%s_lock", company)
	res := gRedisClient.Del(lockName)

	logs.Debug("del lock[%v]:%v ", lockName, res.String())

	return
}

func LoadServiceStatus(appId string) error {

	if gRedisClient == nil {
		return nil
	}

	//循环获取锁
	count := 0
	for count = 0; false == lockSet(appId) && count < 10; count++ {
		time.Sleep(time.Second)
	}

	if count >= 10 {
		logs.Error("%v 获取同步锁超时....", appId)
		return fmt.Errorf("get lock timeout")
	}

	res := gRedisClient.HGetAll(appId)
	if res.Err() != nil {
		logs.Error("connect to redis failed:%v", res.Err())
		return res.Err()
	}

	logs.Debug("companyId:%v,从redis同步坐席状态:%v", appId, res.String())

	for serviceId, status := range res.Val() {
		a, ok := gAgent.Load(appId + serviceId)
		if ok {
			a.(*AgentInfo).UpdataStatus(status)
		} else {
			logs.Warn("service:%v have no local status.", serviceId)
		}
	}

	if count < 10 {
		lockDel(appId)
	}

	return nil
}

func synToRedis(companyId, serviceId, data string) {

	if gRedisClient == nil {
		return
	}
	go func() {

		//获取锁
		for false == lockSet(companyId) {
			time.Sleep(1 * time.Second)
		}

		logs.Debug("appId:%v serviceId:%v 保存坐席状态到redis:%v", companyId, serviceId, data)
		gRedisClient.HSet(companyId, serviceId, data)

		//释放锁
		lockDel(companyId)
	}()
}
